//
// Created by lxinp on 2022/8/30.
//

#ifndef DATASTRUCTURE_HT_ITERATOR_H
#define DATASTRUCTURE_HT_ITERATOR_H

#include "hashtable.h"


template<typename K, typename V>
class HashTable<K, V>::iterator : public std::iterator<std::forward_iterator_tag, std::pair<K, V>> {
public:
    friend class HashTable<K, V>;  // hash table can build iterators with the private constructor

    iterator();
    iterator(const iterator& other);
    const iterator& operator=(const iterator& rhs);
    ~iterator();

    iterator& operator++();    // pre-increment
    iterator operator++(int);  // post-increment
    bool operator==(const iterator& rhs) const;
    bool operator!=(const iterator& rhs) const;

    const std::pair<K, V>& operator*();  // dereference operator
    const std::pair<K, V>* operator->();  // dereference-access operator

private:
    HTIteratorImpl* impl;  /* Implementation for the iterator */

    iterator(HTIteratorImpl* nimpl);  // creates an iterator from an implementation pointer
    void copy(const iterator& other);
    void clear();  // frees dynamic memory associated with the iterator
};


template<typename K, typename V>
class HashTable<K, V>::HTIteratorImpl {
public:
    virtual ~HTIteratorImpl() {}
    virtual HTIteratorImpl* clone() const = 0;
    virtual void operator++() = 0;
    virtual bool operator==(const HTIteratorImpl& rhs) const = 0;
    virtual bool operator!=(const HTIteratorImpl& rhs) const { return !(operator==(rhs)); }
    virtual const std::pair<K, V>& operator*() = 0;
};

#endif //DATASTRUCTURE_HT_ITERATOR_H
